package com.coursebooking.controller;

import com.coursebooking.model.Course;
import com.coursebooking.model.Teacher;
import com.coursebooking.service.CourseService;
import com.coursebooking.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/courses")
@CrossOrigin(origins = "*")
public class CourseController {

    @Autowired
    private CourseService courseService;

    @Autowired
    private TeacherService teacherService;

    // 公开接口 - 获取所有课程
    @GetMapping("/public")
    public ResponseEntity<List<Course>> getAllCoursesPublic() {
        List<Course> courses = courseService.findAll();
        return ResponseEntity.ok(courses);
    }

    // 公开接口 - 根据状态获取课程
    @GetMapping("/public/status/{status}")
    public ResponseEntity<List<Course>> getCoursesByStatusPublic(@PathVariable String status) {
        try {
            Course.CourseStatus courseStatus = Course.CourseStatus.valueOf(status.toUpperCase());
            List<Course> courses = courseService.findByStatus(courseStatus);
            return ResponseEntity.ok(courses);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }

    // 公开接口 - 搜索课程
    @GetMapping("/public/search")
    public ResponseEntity<List<Course>> searchCoursesPublic(@RequestParam String keyword) {
        List<Course> courses = courseService.findByKeyword(keyword);
        return ResponseEntity.ok(courses);
    }

    // 公开接口 - 根据ID获取课程
    @GetMapping("/public/{id}")
    public ResponseEntity<Course> getCourseByIdPublic(@PathVariable Long id) {
        Optional<Course> course = courseService.findById(id);
        return course.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());
    }

    // 需要认证的接口
    @GetMapping
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER') or hasRole('STUDENT')")
    public ResponseEntity<List<Course>> getAllCourses() {
        List<Course> courses = courseService.findAll();
        return ResponseEntity.ok(courses);
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER') or hasRole('STUDENT')")
    public ResponseEntity<Course> getCourseById(@PathVariable Long id) {
        Optional<Course> course = courseService.findById(id);
        return course.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<?> createCourse(@RequestBody CourseRequest courseRequest) {
        try {
            Optional<Teacher> teacherOpt = teacherService.findById(courseRequest.getTeacherId());
            if (!teacherOpt.isPresent()) {
                return ResponseEntity.badRequest().body(new MessageResponse("教师不存在"));
            }

            if (courseService.existsByCode(courseRequest.getCode())) {
                return ResponseEntity.badRequest().body(new MessageResponse("课程代码已存在"));
            }

            Course course = teacherService.createCourse(
                    courseRequest.getName(),
                    courseRequest.getCode(),
                    courseRequest.getDescription(),
                    courseRequest.getCredit(),
                    courseRequest.getHours(),
                    courseRequest.getTeacherId(),
                    courseRequest.getStartTime(),
                    courseRequest.getEndTime(),
                    courseRequest.getLocation(),
                    courseRequest.getMaxStudents()
            );

            return ResponseEntity.ok(course);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("创建课程失败: " + e.getMessage()));
        }
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<?> updateCourse(@PathVariable Long id, @RequestBody CourseRequest courseRequest) {
        try {
            if (!courseService.existsById(id)) {
                return ResponseEntity.notFound().build();
            }

            Optional<Teacher> teacherOpt = teacherService.findById(courseRequest.getTeacherId());
            if (!teacherOpt.isPresent()) {
                return ResponseEntity.badRequest().body(new MessageResponse("教师不存在"));
            }
            Course course = new Course();
            course.setId(id);
            course.setTeacher(teacherOpt.get());
            course.setName(courseRequest.getName());
            course.setCode(courseRequest.getCode());
            course.setDescription(courseRequest.getDescription());
            course.setCredit(courseRequest.getCredit());
            course.setHours(courseRequest.getHours());
            course.setStartTime(courseRequest.getStartTime());
            course.setEndTime(courseRequest.getEndTime());
            course.setLocation(courseRequest.getLocation());
            course.setMaxStudents(courseRequest.getMaxStudents());
            Course entity = courseService.updateCourse(course);

            return ResponseEntity.ok(entity);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("更新课程失败: " + e.getMessage()));
        }
    }

    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<?> updateCourseStatus(@PathVariable Long id, @RequestBody StatusRequest statusRequest) {
        try {
            Course.CourseStatus status = Course.CourseStatus.valueOf(statusRequest.getStatus().toUpperCase());
            Course course = courseService.updateCourseStatus(id, status);
            return ResponseEntity.ok(course);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(new MessageResponse("无效的状态"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("更新状态失败: " + e.getMessage()));
        }
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> deleteCourse(@PathVariable Long id) {
        try {
            courseService.deleteCourse(id);
            return ResponseEntity.ok(new MessageResponse("课程删除成功"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new MessageResponse("删除课程失败: " + e.getMessage()));
        }
    }

    @GetMapping("/teacher/{teacherId}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseEntity<List<Course>> getCoursesByTeacher(@PathVariable Long teacherId) {
        Optional<Teacher> teacherOpt = teacherService.findById(teacherId);
        if (!teacherOpt.isPresent()) {
            return ResponseEntity.notFound().build();
        }
        List<Course> courses = courseService.findByTeacher(teacherOpt.get());
        return ResponseEntity.ok(courses);
    }

    @GetMapping("/time-range")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER') or hasRole('STUDENT')")
    public ResponseEntity<List<Course>> getCoursesByTimeRange(
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        List<Course> courses = courseService.findByTimeRange(startTime, endTime);
        return ResponseEntity.ok(courses);
    }

    // 内部类定义
    public static class CourseRequest {
        private String name;
        private String code;
        private String description;
        private Integer credit;
        private Integer hours;
        private Long teacherId;
        private LocalDateTime startTime;
        private LocalDateTime endTime;
        private String location;
        private Integer maxStudents;

        // Getters and Setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public Integer getCredit() { return credit; }
        public void setCredit(Integer credit) { this.credit = credit; }
        public Integer getHours() { return hours; }
        public void setHours(Integer hours) { this.hours = hours; }
        public Long getTeacherId() { return teacherId; }
        public void setTeacherId(Long teacherId) { this.teacherId = teacherId; }
        public LocalDateTime getStartTime() { return startTime; }
        public void setStartTime(LocalDateTime startTime) { this.startTime = startTime; }
        public LocalDateTime getEndTime() { return endTime; }
        public void setEndTime(LocalDateTime endTime) { this.endTime = endTime; }
        public String getLocation() { return location; }
        public void setLocation(String location) { this.location = location; }
        public Integer getMaxStudents() { return maxStudents; }
        public void setMaxStudents(Integer maxStudents) { this.maxStudents = maxStudents; }
    }

    public static class StatusRequest {
        private String status;

        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
    }

    public static class MessageResponse {
        private String message;

        public MessageResponse(String message) {
            this.message = message;
        }

        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }
}